/*----------------------------------------------------------------------------------------
*
*  Copyright 2019, Gao Hai Hui, <fromzeropoint@126.com>.  All rights reserved.
*  https://gitee.com/helloworldghh/xoskit.git
*  Use of this source code is governed by a MIT license
*  that can be found in the License file.
*
----------------------------------------------------------------------------------------*/
#ifndef __XOS_STL_POOL_XOS_POOL_H__
#define __XOS_STL_POOL_XOS_POOL_H__

namespace xos_stl
{

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // xos_pool

    template< class T, class Lock >
    class xos_pool
    {
    public:
        typedef item_list< T, Lock > LIST;
        typedef typename LIST::const_iterator CONST_ITER;
        typedef typename LIST::iterator ITER;

    protected:
        xos_container::i_container* m_pContainer;
        size_t m_num;
        Lock m_lock;
        LIST m_list;

    protected:
        void init_list( LIST & list, int nNum )
        {
            T* pItem = 0;
            for( int i = 0; i < nNum; ++i )
            {
                init_obj( pItem );
                list.push_back( pItem );
            }
            m_num = list.size();
        }
        void term_list( LIST & list )
        {
            list.delete_all();
            list.clear();
            m_num = 0;
        }
    public:
        xos_pool() : m_pContainer(0), m_num(0)
        {
        }
        ~xos_pool()
        {
            term();
        }
    public:
        int init( xos_container::i_container* pContainer )
        {
            int ret = 0;
            m_pContainer = pContainer;
            return ret;
        }
        int term()
        {
            int ret = 0;
            delete_all();
            return ret;
        }
    public:
        size_t get_total_count()
        {
            size_t num = 0;
            lock();
            num = m_num;
            un_lock();
            return num;
        }
        size_t get_count()
        {
            size_t num = 0;
            lock();
            num = m_list.size();
            un_lock();
            return num;
        }
        T * get_item()
        {
            T * pItem = 0;
            lock();
            if( m_list.size() > 0 )
            {
                pItem = m_list.front();
                m_list.pop_front();
            }
            else
            {
                init_obj( pItem );
                m_num++;
            }
            un_lock();
            return pItem;
        }
        void put_item( T * pT )
        {
            lock();
            m_list.push_back( pT );
            un_lock();
        }
        void delete_all()
        {
            lock();
            term_list( m_list );
            un_lock();
        }
        void un_lock()
        {
            m_lock.un_lock();
        }
        void lock()
        {
            m_lock.lock();
        }

    };

} // xos_stl

#endif // __XOS_STL_POOL_XOS_POOL_H__
